package com.ruoyi.project.tool.swagger.UserController;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.framework.aspectj.lang.annotation.Ide;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.annotation.SignatureValidation;
import com.ruoyi.framework.aspectj.lang.enums.OperatorType;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.interceptor.annotation.RepeatSubmit;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.SysLoginService;
import com.ruoyi.framework.security.service.TokenService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.domain.SysMobileUser;
import com.ruoyi.project.system.domain.SysReceiveCoupon;
import com.ruoyi.project.system.domain.vo.LoginVo;
import com.ruoyi.project.system.domain.vo.UserInfo;
import com.ruoyi.project.system.domain.vo.WxLoginInfo;
import com.ruoyi.project.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/mobileUser/")
@Api(tags = "用户端app登录", description = "用户端app登录")
public class UserController extends BaseController {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysMobileUserService mobileUserService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysReceiveCouponService sysReceiveCouponService;

    @Autowired
    private ISysUserServiceService sysUserServiceService;

    @Autowired
    private ISysFollowService sysFollowService;

    @Autowired
    private ISysDynamicService sysDynamicService;

    @ApiOperation("获取用户详细信息")
    @GetMapping("/getInfo")
    public AjaxResult getUser() {
        SysMobileUser sysMobileUser = mobileUserService.selectSysMobileUserById(SecurityUtils.getLoginUser().getSysMobileUser().getMobileUserId());
        return AjaxResult.success(sysMobileUser);
    }

    @PostMapping(value = "/loginMobile")
    @Log(title = "用户端登录", operatorType = OperatorType.MOBILE)
    @Ide
    @RepeatSubmit
    @SignatureValidation
    @ApiOperation("用户手机号或者用户名登录")
    public AjaxResult login(@RequestBody LoginVo vo) {
        Object token = loginService.loginMobile(vo.getUsername(), vo.getPassword());
        return AjaxResult.success(token);
    }

    @PostMapping(value = "/sendCode")
    @Log(title = "发送验证码", operatorType = OperatorType.MOBILE)
    @Ide
    @RepeatSubmit
    @SignatureValidation
    @ApiOperation("用户注册发送验证码")
    public AjaxResult sendCode(@RequestBody Map map) {
        if (null == map.get("phone")) {
            return AjaxResult.error("手机号为空");
        }
        if (null == map.get("type")) {
            return AjaxResult.error("发送短信类型不能为空");
        }
        //生成随机验证码
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        // 唯一标识
        Object uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.PHONE_CODE_KEY + uuid;
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAIczMIIOROcM0x", "otBV5lJdw3ZV7PWBEv8uqbsRPI3MaX");
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", map.get("phone") + "");
        request.putQueryParameter("SignName", "jjp");
        request.putQueryParameter("TemplateCode", "SMS_139455225");
        request.putQueryParameter("TemplateParam", "{\"code\":" + verifyCode + "}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            JSONObject jsonObject = JSONObject.parseObject(response.getData());
            if (jsonObject.getString("Code").equals("OK")) {
                redisCache.setCacheObject(verifyKey, verifyCode, Constants.PHONE_EXPIRATION, TimeUnit.MINUTES);
                return AjaxResult.success(uuid);
            } else {
                return AjaxResult.error(jsonObject.getString("Message"));
            }
        } catch (Exception e) {
            throw new BaseException("发送验证码失败");
        }
    }

    @PostMapping(value = "/register")
    @Log(title = "用户端注册", operatorType = OperatorType.MOBILE)
    @Ide
    @RepeatSubmit
    @SignatureValidation
    @ApiOperation("用户端注册")
    public AjaxResult login(@RequestBody Map map) {
        if (null == map.get("phone")) {
            return AjaxResult.error("手机号为空");
        }
        if (null == map.get("password")) {
            return AjaxResult.error("密码为空");
        }
        if (null == map.get("code")) {
            return AjaxResult.error("短信验证码为空");
        }
        if (null == map.get("key")) {
            return AjaxResult.error("验证码值为空");
        }
        String verifyKey = Constants.PHONE_CODE_KEY + map.get("key");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            return AjaxResult.error("验证码失效");
        }
        if (!(map.get("code") + "").equalsIgnoreCase(captcha)) {
            return AjaxResult.error("验证码错误");
        }
        SysMobileUser sysMobileUser = new SysMobileUser();
        sysMobileUser.setPassword(SecurityUtils.encryptPassword(map.get("password") + ""));
        sysMobileUser.setPhone(map.get("phone") + "");
        sysMobileUser.setStatus("0");
        sysMobileUser.setDelFlag("0");

        SysMobileUser user = mobileUserService.selectSysMobileUserByName(map.get("phone") + "");
        if (null != user) {
            return AjaxResult.error("用户已存在!");
        }
        int flag = mobileUserService.insertSysMobileUser(sysMobileUser);
        if (flag == 1) {
            return AjaxResult.success("注册成功");
        }
        return AjaxResult.error("注册失败");
    }


    @PostMapping(value = "/codeLogin")
    @Log(title = "动态验证码登录", operatorType = OperatorType.MOBILE)
    @Ide
    @RepeatSubmit
    @SignatureValidation
    @ApiOperation("动态验证码登录")
    public AjaxResult codeLogin(@RequestBody Map map) {
        if (null == map.get("phone")) {
            return AjaxResult.error("手机号为空");
        }
        if (null == map.get("code")) {
            return AjaxResult.error("短信验证码为空");
        }
        if (null == map.get("key")) {
            return AjaxResult.error("验证码值为空");
        }
        String verifyKey = Constants.PHONE_CODE_KEY + map.get("key");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            return AjaxResult.error("验证码失效");
        }
        if (!(map.get("code") + "").equalsIgnoreCase(captcha)) {
            return AjaxResult.error("验证码错误");
        }
        SysMobileUser sysMobileUser = mobileUserService.selectSysMobileUserByName(map.get("phone") + "");
        if (null == sysMobileUser) {
            return AjaxResult.success("手机号尚未注册!");
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setSysMobileUser(sysMobileUser);
        loginUser.setUserName(sysMobileUser.getUserName());
        Object token = tokenService.createToken(loginUser);
        return AjaxResult.success(token);
    }

    /**
     * 微信授权登录
     */
    @Ide
    @PostMapping("authorizedLogin")
    public AjaxResult insertMobileUser(@RequestBody WxLoginInfo wxLoginInfo) throws Exception {
        Map map = new HashMap();
        String path = RuoYiConfig.getProfile() + IdUtil.simpleUUID() + ".jpg";
        String code = wxLoginInfo.getCode();
        UserInfo userInfo = wxLoginInfo.getUserInfo();
        if ("".equals(code) || null == userInfo) {
            return AjaxResult.error("参数不正确");
        }
        String sessionKey = null;
        String openId = null;
        try {
            WxMaJscode2SessionResult result = this.wxMaService.getUserService().getSessionInfo(code);
            sessionKey = result.getSessionKey();
            openId = result.getOpenid();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (sessionKey == null || openId == null) {
            return AjaxResult.error("错误");
        }

        SysMobileUser sysMobileUser = mobileUserService.queryUserOpenId(openId);
        if (null == sysMobileUser) {
            sysMobileUser = new SysMobileUser();
            sysMobileUser.setUserName(userInfo.getNickName());
            sysMobileUser.setOpenId(openId);

            if (userInfo.getGender().equals("1")) {
                SysDictData sysDictData = sysDictDataService.querySex("男");
                sysMobileUser.setSex(sysDictData.getDictValue());
            }
            if (userInfo.getGender().equals("2")) {
                SysDictData sysDictData = sysDictDataService.querySex("女");
                sysMobileUser.setSex(sysDictData.getDictValue());
            }

            sysMobileUser.setDelFlag("0");

            String avatarUrl = ImageUtils.downloadPicture(userInfo.getAvatarUrl(), path);
            MultipartFile mulFile = MutipartUtils.getMulFileByPath(avatarUrl);
            sysMobileUser.setImage(MutipartUtils.uploadFile(mulFile));

//          UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(sysMobileUser.getUserName(), openId);
//          String token = loginService.loginMobile(sysMobileUser.getUserName(),openId);

            mobileUserService.insertSysMobileUser(sysMobileUser);
            LoginUser loginUser = new LoginUser();
            loginUser.setSysMobileUser(mobileUserService.selectSysMobileUserById(sysMobileUser.getMobileUserId()));
            loginUser.setUserName(sysMobileUser.getUserName());
            loginUser.setPassword(openId);
            String token = tokenService.createToken(loginUser);
            userInfo.setMobileUserId(sysMobileUser.getMobileUserId());
            map.put("token", token);
            map.put("userInfo", userInfo);
            return AjaxResult.success(map);
        } else {
//          UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(sysMobileUser.getUserName(), openId);
//          String token = loginService.loginMobile(sysMobileUser.getUserName(),openId);
            LoginUser loginUser = new LoginUser();
            loginUser.setSysMobileUser(mobileUserService.selectSysMobileUserById(sysMobileUser.getMobileUserId()));
            loginUser.setUserName(sysMobileUser.getUserName());
            loginUser.setPassword(openId);
            String token = tokenService.createToken(loginUser);
            userInfo.setMobileUserId(sysMobileUser.getMobileUserId());
            map.put("token", token);
            map.put("userInfo", userInfo);
            return AjaxResult.success(map);
        }
    }

    @GetMapping("queryCountAll")
    public AjaxResult queryCountAll() {
        Long mobileUserId = SecurityUtils.getLoginUser().getSysMobileUser().getMobileUserId();
        Map map = new HashMap();
        int couponCount = sysReceiveCouponService.queryCouponCountByUser(mobileUserId);
        map.put("couponCount",couponCount);
        int serviceCount = sysUserServiceService.queryAllServiceCount(mobileUserId);
        map.put("serviceCount",serviceCount);
        int fensiCount = sysFollowService.queryFensiNum(mobileUserId);
        map.put("fensiCount",fensiCount);
        int dynamicMum = sysDynamicService.queryDynamicMum(mobileUserId);
        map.put("dynamicMum",dynamicMum);
        return AjaxResult.success(map);
    }
}